home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / a_rotate.asm < prev    next >
Encoding:
Assembly Source File  |  2001-03-20  |  8.1 KB  |  487 lines

  1. ;    VirtualDub - Video processing and capture application
  2. ;    Copyright (C) 1998-2001 Avery Lee
  3. ;
  4. ;    This program is free software; you can redistribute it and/or modify
  5. ;    it under the terms of the GNU General Public License as published by
  6. ;    the Free Software Foundation; either version 2 of the License, or
  7. ;    (at your option) any later version.
  8. ;
  9. ;    This program is distributed in the hope that it will be useful,
  10. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;    GNU General Public License for more details.
  13. ;
  14. ;    You should have received a copy of the GNU General Public License
  15. ;    along with this program; if not, write to the Free Software
  16. ;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.  
  19.     .586
  20.     .387
  21.     .mmx
  22.     .model    flat
  23.  
  24.     .const
  25.  
  26. x0100010001000100 dq 0100010001000100h
  27. x0080008000800080 dq 0080008000800080h
  28.  
  29. point_jumptbl    dd    off0, 0
  30.         dd    off7, -28
  31.         dd    off6, -24
  32.         dd    off5, -20
  33.         dd    off4, -16
  34.         dd    off3, -12
  35.         dd    off2, -8
  36.         dd    off1, -4
  37.  
  38.     .code
  39.  
  40.     extern _MMX_enabled : byte
  41.     extern _FPU_enabled : byte
  42.  
  43.     public    _asm_rotate_point
  44.  
  45. ;    void asm_rotate_point(
  46. ;        [esp+ 4] Pixel *src,
  47. ;        [esp+ 8] Pixel *dst,
  48. ;        [esp+12] long width,
  49. ;        [esp+16] long Ufrac,
  50. ;        [esp+20] long Vfrac,
  51. ;        [esp+24] long UVintstepV,
  52. ;        [esp+28] long UVintstepnoV,
  53. ;        [esp+32] long Ustep,
  54. ;        [esp+36] long Vstep);
  55.  
  56. _asm_rotate_point:
  57.     push    eax
  58.     push    ebx
  59.     push    ecx
  60.     push    edx
  61.     push    esi
  62.     push    edi
  63.     push    ebp
  64.  
  65.     mov    esi,[esp +  4 + 28]
  66.     mov    eax,[esp + 12 + 28]
  67.     mov    edi,[esp +  8 + 28]
  68.     mov    ebx,eax
  69.     mov    ecx,[esp + 16 + 28]
  70.     shl    ebx,2
  71.     mov    edx,[esp + 20 + 28]
  72.     add    ebx,edi
  73.     mov    ebp,[esp + 32 + 28]
  74.     shr    esi,2
  75.     mov    [esp + 12 + 28], ebx
  76.  
  77. ;on entry into loop:
  78. ;
  79. ;    EAX    temporary for pixel copy
  80. ;    EBX    temporary for carry flag
  81. ;    ECX    Ufrac
  82. ;    EDX    Vfrac
  83. ;    ESI    source
  84. ;    EDI    dest
  85. ;    EBP    U increment
  86. ;
  87. ; This is why inline assembler don't always cut it... there is no way
  88. ; to define a jump table with entry points into the middle of a function!
  89. ;
  90. ; texmap codelet courtesy of Chris Hacker's texture mapping article...
  91.  
  92. POINTPIX macro    dstoff
  93.     add    ecx,ebp
  94.     mov    eax,[esi*4]
  95.  
  96.     adc    esi,[esp + 28 + 28 + ebx*4]
  97.     add    edx,dword ptr [esp+36+28]
  98.  
  99.     sbb    ebx,ebx
  100.     mov    [edi+dstoff*4],eax
  101.     endm
  102.  
  103.     ; figure out EDI and jump offsets
  104.  
  105.     and    eax,7
  106.     add    edi,dword ptr [point_jumptbl + eax*8 + 4]
  107.  
  108.     add    edx,dword ptr [esp+36+28]
  109.     sbb    ebx,ebx
  110.  
  111.     jmp    dword ptr [point_jumptbl + eax*8]
  112.  
  113.     align    16
  114. xloop:
  115.  
  116. off0:    POINTPIX    0
  117. off1:    POINTPIX    1
  118. off2:    POINTPIX    2
  119. off3:    POINTPIX    3
  120. off4:    POINTPIX    4
  121. off5:    POINTPIX    5
  122. off6:    POINTPIX    6
  123. off7:    POINTPIX    7
  124.  
  125.     add    edi,4*8
  126.     cmp    edi,[esp + 12 + 28]
  127.  
  128.     jne    xloop
  129.  
  130.     pop    ebp
  131.     pop    edi
  132.     pop    esi
  133.     pop    edx
  134.     pop    ecx
  135.     pop    ebx
  136.     pop    eax
  137.  
  138.     ret
  139.  
  140. ;**************************************************************************
  141.  
  142.     public    _asm_rotate_bilinear
  143.  
  144. ;    void asm_rotate_bilinear(
  145. ;        [esp+ 4] Pixel *src,
  146. ;        [esp+ 8] Pixel *dst,
  147. ;        [esp+12] long width,
  148. ;        [esp+16] long pitch,
  149. ;        [esp+20] long Ufrac,
  150. ;        [esp+24] long Vfrac,
  151. ;        [esp+28] long UVintstepV,
  152. ;        [esp+32] long UVintstepnoV,
  153. ;        [esp+36] long Ustep,
  154. ;        [esp+40] long Vstep);
  155.  
  156. _asm_rotate_bilinear:
  157.     test    _MMX_enabled,1
  158.     jnz    _asm_rotate_bilinear_MMX
  159.  
  160.     push    eax
  161.     push    ebx
  162.     push    ecx
  163.     push    edx
  164.     push    esi
  165.     push    edi
  166.     push    ebp
  167.  
  168.     push    eax
  169.  
  170.  
  171. l_source    = 32 + 4
  172. l_dest        = 32 + 8
  173. l_destlimit    = 32 + 12
  174. l_pitch        = 32 + 16
  175. l_Ufrac        = 32 + 20
  176. l_Vfrac        = 32 + 24
  177. l_UVinctbl    = 32 + 28
  178. l_Ustep        = 32 + 36
  179. l_Vstep        = 32 + 40
  180. l_co3        = 0
  181.  
  182.     mov    eax,[esp + l_destlimit]
  183.     mov    edx,[esp + l_dest]
  184.     shl    eax,2
  185.     mov    edi,[esp + l_source]
  186.     add    eax,edx
  187.     shr    edi,2
  188.     mov    [esp + l_destlimit], eax
  189.  
  190. ;on entry into loop:
  191. ;
  192. ;    ECX    V fraction
  193. ;    EDX    U fraction >> 24
  194. ;    EDI    source address
  195.  
  196.     mov    edx,[esp+l_Ufrac]
  197.     mov    ecx,[esp+l_Vfrac]
  198.     shr    edx,24
  199.  
  200. xloop_bilinear:
  201.     ;compute coefficients and fetch pixels
  202.  
  203.     shr    ecx,24                ;ecx = bottom half
  204.     mov    ebx,edx                ;ebx = right half
  205.  
  206.     imul    edx,ecx                ;edx = bottom right
  207.  
  208.     shr    edx,8
  209.  
  210.     sub    ecx,edx                ;ecx = bottom left
  211.  
  212.     mov    esi,ebx
  213.     sub    ebx,edx                ;ebx = top right
  214.  
  215.     add    esi,ecx                ;esi = !top left
  216.     mov    [esp+l_source],edi        ;store updated source pixel address
  217.  
  218.     mov    eax,256
  219.     mov    ebp,[esp+l_pitch]
  220.  
  221.     sub    eax,esi
  222.     mov    esi,[edi*4 + ebp + 4]        ;esi = bottom right pixel
  223.  
  224.     mov    edi,esi
  225.     and    esi,00ff00ffh            ;esi = bottom right red/blue
  226.  
  227.     and    edi,0000ff00h            ;edi = bottom right green
  228.     mov    [esp+l_co3],ecx
  229.  
  230.     imul    esi,edx                ;esi = scaled bottom right red/blue
  231.     imul    edi,edx                ;edi = scaled bottom right green
  232.  
  233.     ;do bottom left pixel
  234.  
  235.     mov    edx,[esp+l_source]
  236.     mov    ecx,00ff00ffh
  237.  
  238.     mov    edx,[edx*4 + ebp]
  239.     mov    ebp,[esp+l_source]
  240.  
  241.     and    ecx,edx
  242.     and    edx,0000ff00h
  243.  
  244.     imul    ecx,[esp+l_co3]
  245.     imul    edx,[esp+l_co3]
  246.  
  247.     add    esi,ecx
  248.     add    edi,edx
  249.  
  250.     ;do top left pixel
  251.  
  252.     mov    edx,[ebp*4]
  253.     mov    ecx,00ff00ffh
  254.  
  255.     and    ecx,edx
  256.     and    edx,0000ff00h
  257.  
  258.     imul    ecx,eax
  259.     imul    edx,eax
  260.  
  261.     add    esi,ecx
  262.     add    edi,edx
  263.  
  264.     ;do top right pixel
  265.  
  266.     mov    edx,[ebp*4+4]
  267.     mov    ecx,00ff00ffh
  268.  
  269.     and    ecx,edx
  270.     and    edx,0000ff00h
  271.  
  272.     imul    ecx,ebx
  273.     imul    edx,ebx
  274.  
  275.     add    esi,ecx
  276.     add    edi,edx
  277.  
  278.     ;finish up pixel
  279.  
  280.     add    esi,00800080h
  281.     add    edi,00008000h
  282.  
  283.     shr    esi,8
  284.     and    edi,00ff0000h
  285.  
  286.     shr    edi,8
  287.     and    esi,00ff00ffh
  288.  
  289.     mov    eax,[esp+l_dest]
  290.     or    esi,edi
  291.  
  292.     mov    [eax],esi
  293.     add    eax,4
  294.  
  295.     ;update address and loop
  296.  
  297.     mov    edx,[esp+l_Ufrac]
  298.     mov    ecx,[esp+l_Vfrac]
  299.  
  300.     add    ecx,[esp+l_Vstep]
  301.  
  302.     sbb    ebx,ebx
  303.     add    edx,[esp+l_Ustep]
  304.  
  305.     mov    [esp+l_Ufrac],edx
  306.     mov    [esp+l_Vfrac],ecx
  307.  
  308.     adc    ebp,[esp+l_UVinctbl+4+ebx*4]
  309.     mov    [esp+l_dest],eax
  310.  
  311.     shr    edx,24
  312.     mov    edi,ebp
  313.  
  314.     cmp    eax,[esp+l_destlimit]
  315.     jne    xloop_bilinear
  316.  
  317.     pop    eax
  318.  
  319.     pop    ebp
  320.     pop    edi
  321.     pop    esi
  322.     pop    edx
  323.     pop    ecx
  324.     pop    ebx
  325.     pop    eax
  326.  
  327.     ret
  328.  
  329. ;**************************************************************************
  330.  
  331.     public    _asm_rotate_bilinear
  332.  
  333. ;    void asm_rotate_bilinear(
  334. ;        [esp+ 4] Pixel *src,
  335. ;        [esp+ 8] Pixel *dst,
  336. ;        [esp+12] long width,
  337. ;        [esp+16] long pitch,
  338. ;        [esp+20] long Ufrac,
  339. ;        [esp+24] long Vfrac,
  340. ;        [esp+28] long UVintstepV,
  341. ;        [esp+32] long UVintstepnoV,
  342. ;        [esp+36] long Ustep,
  343. ;        [esp+40] long Vstep);
  344.  
  345. _asm_rotate_bilinear_MMX:
  346.     push    eax
  347.     push    ebx
  348.     push    ecx
  349.     push    edx
  350.     push    esi
  351.     push    edi
  352.     push    ebp
  353.  
  354. l_source    = 28 + 4
  355. l_dest        = 28 + 8
  356. l_destlimit    = 28 + 12
  357. l_pitch        = 28 + 16
  358. l_Ufrac        = 28 + 20
  359. l_Vfrac        = 28 + 24
  360. l_UVinctbl    = 28 + 28
  361. l_Ustep        = 28 + 36
  362. l_Vstep        = 28 + 40
  363.  
  364.     mov    eax,[esp + l_destlimit]
  365.     mov    edi,[esp + l_dest]
  366.     shl    eax,2
  367.     mov    esi,[esp + l_source]
  368.     add    eax,edi
  369.     shr    esi,2
  370.     mov    [esp + l_destlimit], eax
  371.  
  372. ;on entry into loop:
  373. ;
  374. ;    ECX    V fraction
  375. ;    EDX    U fraction >> 24
  376. ;    ESI    source address
  377. ;    EDI    dest address
  378. ;    EBP    row pitch
  379.  
  380.     mov    edx,[esp+l_Ufrac]
  381.     mov    ecx,[esp+l_Vfrac]
  382.     mov    ebp,[esp+l_pitch]
  383.     shr    edx,24
  384.  
  385. xloop_bilinearMMX:
  386.     ;compute coefficients and fetch pixels
  387.  
  388.     shr    ecx,24                ;ecx = bottom half
  389.     mov    ebx,edx                ;ebx = right half
  390.  
  391.     imul    edx,ecx                ;edx = bottom right
  392.  
  393.     shr    edx,8
  394.  
  395.     movd    mm6,ecx
  396.     mov    eax,edx
  397.  
  398.     shl    edx,16
  399.     punpcklwd mm6,mm6
  400.  
  401.     movq    mm4,x0100010001000100
  402.     mov    ecx,ebx    
  403.  
  404.     shl    ebx,16
  405.     or    edx,eax
  406.  
  407.     movd    mm7,edx
  408.     punpckldq mm6,mm6            ;mm6 = bottom half
  409.  
  410.     punpckldq mm7,mm7            ;mm7 = bottom-right
  411.     or    ebx,ecx
  412.  
  413.     movd    mm5,ebx
  414.     psubw    mm4,mm6                ;mm4 = top half
  415.  
  416.     punpckldq mm5,mm5            ;mm5 = right half
  417.     psubw    mm6,mm7                ;mm6 = bottom-left
  418.  
  419.     psubw    mm5,mm7                ;mm7 = top-right
  420.  
  421.     psubw    mm4,mm5                ;mm4 = top-left
  422.  
  423.     ;do pixels
  424.  
  425.     movd    mm0,[esi*4+0]
  426.     pxor    mm3,mm3
  427.  
  428.     movd    mm1,[esi*4+4]
  429.     punpcklbw mm0,mm3
  430.  
  431.     pmullw    mm0,mm4
  432.     punpcklbw mm1,mm3
  433.  
  434.     movd    mm2,[esi*4+ebp+0]
  435.     pxor    mm4,mm4
  436.  
  437.     pmullw    mm1,mm5
  438.     punpcklbw mm2,mm4
  439.  
  440.     movd    mm3,[esi*4+ebp+4]
  441.     pmullw    mm2,mm6
  442.  
  443.     paddw    mm0,x0080008000800080
  444.     punpcklbw mm3,mm4
  445.  
  446.     pmullw    mm3,mm7
  447.     paddw    mm0,mm1
  448.  
  449.     paddw    mm0,mm2
  450.     mov    edx,[esp+l_Ufrac]
  451.  
  452.     paddw    mm0,mm3
  453.     mov    ecx,[esp+l_Vfrac]
  454.  
  455.     psrlw    mm0,8
  456.     add    edi,4
  457.  
  458.     packuswb mm0,mm0
  459.     add    ecx,[esp+l_Vstep]
  460.  
  461.     sbb    ebx,ebx
  462.     add    edx,[esp+l_Ustep]
  463.  
  464.     mov    [esp+l_Ufrac],edx
  465.     mov    [esp+l_Vfrac],ecx
  466.  
  467.     adc    esi,[esp+l_UVinctbl+4+ebx*4]
  468.  
  469.     shr    edx,24
  470.     cmp    edi,[esp+l_destlimit]
  471.  
  472.     movd    [edi-4],mm0
  473.     jne    xloop_bilinearMMX
  474.  
  475.     pop    ebp
  476.     pop    edi
  477.     pop    esi
  478.     pop    edx
  479.     pop    ecx
  480.     pop    ebx
  481.     pop    eax
  482.  
  483.     emms
  484.     ret
  485.  
  486.     end
  487.